<?php

namespace App\Models;

use App\Exceptions\ApiExceptions;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;
use SuperEggs\DcatDistpicker\DcatDistpickerHelper;
use Illuminate\Database\Eloquent\Builder;

class JobpositionModel extends AbstractBaseModel implements Sortable
{
    use SoftDeletes, SortableTrait;

    const CREATED_MAN = 1;
    const UPDATED_GIRL = 2;
    const DELETED_UNLIMITED = 3;
    const GENDER_LIST = [
        self::CREATED_MAN => '男',
        self::UPDATED_GIRL => '女',
        self::DELETED_UNLIMITED => '性别不限'
    ];

    const CONTACT_MOBILE = 1; //手机
    const CONTACT_QQ = 2; //qq
    const CONTACT_WECHAT = 3; //微信
    const CONTACT_DINGTALK = 4; //钉钉
    const CONTACT_TYPE_LIST = [
        self::CONTACT_MOBILE => '手机',
        self::CONTACT_QQ => 'qq',
        self::CONTACT_WECHAT => '微信',
        self::CONTACT_DINGTALK => '钉钉',
    ];

    const SALARY_TYPE_HOURLY = 1; // 单
    const SALARY_TYPE_HOUR = 2; // 时

    const SALARY_TYPE_DAILY = 3; // 日
    const SALARY_TYPE_WEEKLY = 4; // 周
    const SALARY_TYPE_MONTHLY = 5; // 月

    const SALARY_TYPE_LIST = [
        self::SALARY_TYPE_HOURLY => '元/单',
        self::SALARY_TYPE_HOUR => '元/小时',
        self::SALARY_TYPE_DAILY => '元/天',
        self::SALARY_TYPE_WEEKLY => '元/周',
        self::SALARY_TYPE_MONTHLY => '元/月',
    ];


    const TYPE_DATE = 1;
    const TYPE_NUMBER = 2;

    const TYPE_LIST = [
        self::TYPE_DATE => '到期时间',
        self::TYPE_NUMBER => '招聘人数',
    ];
    //后台设置标签
    const LABEL_LIST = [
        1 => '近期热门',
        2 => '回复及时',
        3 => '结单快'
    ];
    //标题处的标签
    const TITLE_TAG = [
        1 => '新',
        2 => '急'
    ];

    const WORK_EXPERIENCE_LIST = [
        0 => '无需经验',
        1 => '需要经验',
    ];

    const STATUS_ON_LINE = 1; //上线中
    const STATUS_OFF_LINE = 2; //已下线
    const STATUS_CHECK_AWAIT = 3; //待审核
    const STATUS_AWAIT_REJECT = 4; //审核驳回

    const STATUS_LIST = [
        self::STATUS_ON_LINE => '已上架',
        self::STATUS_OFF_LINE => '已下架',
        self::STATUS_CHECK_AWAIT => '待审核',
        self::STATUS_AWAIT_REJECT => '审核驳回',
    ];
    const CREATED_UNLIMITED = 0;
    const CREATED_HIGHSCHOOL = 1;
    const UPDATED_JUNIORCONLLEGE = 2;
    const DELETED_UNDERGRADUATE = 3;
    const DELETED_MASTER = 4;
    const DELETED_DOCTOR = 5;
    const GENDER_EDUCATION = [
        self::CREATED_UNLIMITED => '学历不限',
        self::CREATED_HIGHSCHOOL => '高中/中专',
        self::UPDATED_JUNIORCONLLEGE => '大专',
        self::DELETED_UNDERGRADUATE => '本科',
        self::DELETED_MASTER => '硕士',
        self::DELETED_DOCTOR => '博士',
    ];
    const CONTACT_GENRE_ORDER = 1;
    const CONTACT_GENRE_RAND = 2;
    const CONTACT_GENRE_LIST = [
        self::CONTACT_GENRE_ORDER => '顺次推荐',
        self::CONTACT_GENRE_RAND => '随机推荐'

    ];
    protected $table = 'job_position';
    protected $sortable = [
        // 设置排序字段名称
        //        'order_column_name' => 'sort',
        // 是否在创建时自动排序，此参数建议设置为true
        'sort_when_creating' => false,
    ];
    protected $casts = [
        'tags' => 'json',
    ];

    // 定义多对多关系
    public function categories()
    {
        return $this->belongsToMany(CategoryModel::class, jobPositionCategoryModel::class, 'job_position_id', 'category_id')
            ->withTimestamps();
    }

    // 定义多对多关系
    public function platforms()
    {
        return $this->belongsToMany(PlatformModel::class, jobPositionPlatformModel::class, 'job_position_id', 'platform_id')
            ->withTimestamps();
    }

    /**
     * 关联模式
     * @return BelongsTo
     */
    public function company()
    {
        return $this->belongsTo(CompanyModel::class, 'company_id');
    }

    /**
     * @return HasOne
     */
    public function statistics(): HasOne
    {
        return $this->HasOne(JobpositionStatisticsModel::class, 'job_position_id');
    }

    public function checkInfo(): HasOne
    {
        return $this->HasOne(JobPositionCheckModel::class, 'job_position_id')->orderByDesc('id');
    }

    public function contactWechat(): HasMany
    {
        return $this->HasMany(JobPositionContactWechatModel::class, 'job_position_id')->orderBy('sort');
    }

    public function contactQq(): HasMany
    {
        return $this->HasMany(JobPositionContactQqModel::class, 'job_position_id')->orderBy('sort');
    }

    public function contactPhone(): HasMany
    {
        return $this->HasMany(JobPositionContactPhoneModel::class, 'job_position_id')->orderBy('sort');
    }

    public function contactDingtalk(): HasMany
    {
        return $this->HasMany(JobPositionContactDingtalkModel::class, 'job_position_id')->orderBy('sort');
    }


    /**
     * 检查职位是否可用
     * @param JobpositionModel $info
     * @param Authenticatable|User|null $user
     * @return void
     * @throws ApiExceptions
     */
    public function checkAvailability(Authenticatable|User|null $user = null)
    {
        if ($user) {
            //登录用户做年龄性别限制
            $age = $user->age();
            if ($age != -1) {
                if ($this->min_age != 0 && $this->min_age > $age) {
                    throw new ApiExceptions("不符合职位要求");
                    //                        throw new ApiExceptions("年龄不符合,最小年龄为：$this->min_age");
                }
                if ($this->max_age != 0 && $this->max_age < $age) {
                    throw new ApiExceptions("不符合职位要求");
                    //                        throw new ApiExceptions("年龄不符合,最大年龄为：$this->max_age");
                }
            }
            //登录用户做性别限制
            if (in_array($this->gender_requirement, [self::CREATED_MAN, self::UPDATED_GIRL])) {
                if ($this->gender_requirement != $user->gender) {
                    throw new ApiExceptions("不符合职位要求");
                    //                        throw new ApiExceptions("该职位招聘要求性别:" . self::GENDER_LIST[$this->gender_requirement]);
                }
            }
        }
    }

    public function vrStatus()
    {
        $now = now();
        $day = $now->format('Y-m-d');
        $hour = $now->format('H:i:s');
        $date = $now->format('Y-m-d H:i:s');
        if ($this->selection_date_start != null && $this->selection_date_start > $day) {
            return 0;
        }
        if ($this->selection_date_end != null && $this->selection_date_end < $day) {
            return 0;
        }
        if ($this->selection_date_end != null && $this->selection_date_end < $day) {
            return 0;
        }
        if ($this->work_time_start != null && $this->work_time_start > $hour) {
            return 0;
        }
        if ($this->work_time_end != null  && $this->work_time_end < $hour) {
            return 0;
        }
        if ($this->cur_type == self::TYPE_DATE && $this->expiration_date < $date) {
            return 0;
        }
        if ($this->cur_type == self::TYPE_NUMBER && $this->expected_num <= $this->recruit_num) {
            //人数招满
            return 0;
        }
        if ($this->company->is_lock != CompanyModel::VERIFY_WAIT) {
            return 0;
        }
        //        if ($this->company->is_lock != CompanyModel::VERIFY_WAIT || $this->company->registration_num <= 0){
        //            return 0;
        //        }
        return 1;
    }

    /**
     * 是否申请
     * @param Authenticatable|User|null $user
     * @return bool
     */
    public function is_apply(Authenticatable|User|null $user = null): bool
    {
        if (!$user) return false;
        return SignUpJobpositionModel::query()->where([
            ['user_id', $user->id],
            ['job_position_id', $this->id]
        ])->exists();
    }

    /**
     * 是否收藏
     * @param Authenticatable|User|null $user
     * @return bool
     */
    public function is_collect(Authenticatable|User|null $user = null): bool
    {
        if (!$user) return false;
        return JobPositionCollectModel::query()->where([
            ['user_id', $user->id],
            ['job_position_id', $this->id]
        ])->exists();
    }

    public function regionInfo()
    {
        if (!$this->region_region) {
            return '不限地点';
        }
        return DcatDistpickerHelper::getAreaName($this->region_city) . DcatDistpickerHelper::getAreaName($this->region_region);
    }

    /**
     * 基础查询条件
     * @param Builder $query
     * @return Builder
     */
    public function scopeValidPositions(Builder $query): Builder
    {
        // 计算当前时间的日期和时间格式
        $now = now();
        $day = $now->format('Y-m-d');
        $hour = $now->format('H:i:s');
        $date = $now->format('Y-m-d H:i:s');

        return
            $query
            ->where('cur_status', self::STATUS_ON_LINE)
            ->withWhereHas('company', function ($query) {
                $query->where('is_lock', CompanyModel::VERIFY_WAIT);
                //                    $query->where('is_lock', CompanyModel::VERIFY_WAIT)->where('registration_num','>',0);
            })->where(function ($query) use ($day) {
                $query->where('selection_date_start', '<=', $day)
                    ->orWhereNull('selection_date_start');
            })->where(function ($query) use ($day) {
                $query->where('selection_date_end', '>=', $day)
                    ->orWhereNull('selection_date_end');
            })->where(function ($query) use ($hour) {
                $query->where('work_time_end', '>', $hour)
                    ->orWhereNull('work_time_end');
            })->where(function ($query) use ($hour) {
                $query->where('work_time_start', '<=', $hour)
                    ->orWhereNull('work_time_start');
            })->where(function ($query) use ($date) {
                $query->where(function ($query) use ($date) {
                    $query->where('cur_type', 1)
                        ->where('expiration_date', '>', $date);
                })->orWhere(function ($query) {
                    $query->where('cur_type', 2)
                        ->whereRaw('`expected_num` > `recruit_num`');
                });
            });
    }
}
